<?php

require_once 'BancoDeDados.php';

/**
 * Recurso Classe do Objeto e do Thesaurus
 */
class Classe {

    private $cod_classe;
    private $classe_pai;
    private $codigo;
    private $descricao;
    private $nome;
    private $classesFilhas = array();
    private $vinculado;

    public function &getCod_classe() {
        return $this->cod_classe;
    }

    public function setCod_classe(&$cod_classe) {
        $this->cod_classe = &$cod_classe;
    }

    /**
     *
     * @return Classe
     */
    public function &getClasse_pai() {
        return $this->classe_pai;
    }

    public function setClasse_pai(Classe &$classe_pai) {
        $this->classe_pai = &$classe_pai;
    }

    public function &getCodigo() {
        return $this->codigo;
    }

    public function setCodigo(&$codigo) {
        $this->codigo = &$codigo;
    }

    public function &getDescricao() {
        return $this->descricao;
    }

    public function setDescricao(&$Descricao) {
        $this->descricao = &$Descricao;
    }

    public function &getNome() {
        return $this->nome;
    }

    public function setNome(&$nome) {
        $this->nome = &$nome;
    }

    public function &getClassesFilhas() {
        return $this->classesFilhas;
    }

    public function setClassesFilhas(&$classesFilhas) {
        $this->classesFilhas = &$classesFilhas;
    }

    public function &isVinculado() {
        return $this->vinculado;
    }

    private function setVinculado(&$vinculado) {
        $this->vinculado = &$vinculado;
    }

    /**
     * @method void cadastrar() para cadastro do recurso
     * Para que este possa ser utilizado ao menos a descricao e o nome da classe não pode ser vazio
     * @return void
     */
    public function cadastrar() {
        if ($this->validar() != 1) {
            throw new Exception("Classe existente");
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        if ($this->classe_pai instanceof Classe) {
            $stmt = $link->prepare('insert into classe (descricao, nome, classe_pai) values(?,?,?)');
            $result = $link->execute($stmt, array($this->descricao, $this->nome, $this->classe_pai->getCod_classe()));
        } else {
            $stmt = $link->prepare('insert into classe (descricao, nome) values(?,?)');
            $result = $link->execute($stmt, array($this->descricao, $this->nome));
        }
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public function alterarCampo(&$campo_id, &$campo_valor) {
        if ($campo_id == 'nome' && $this->nome != $campo_valor) {
            $this->nome = &$campo_valor;
            if ($this->validar() != 1) {
                throw new Exception("Classe existente");
            }
        } else if ($campo_id == 'descricao' && $this->descricao != $campo_valor) {
            $this->descricao = &$campo_valor;
        } else {
            throw new Exception('no_action');
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('update classe set ' . $campo_id . ' = ? where cod_classe = ?');
        $result = $link->execute($stmt, array($campo_valor, $this->cod_classe));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    /**
     * @method void excluir() para exclusão do recurso
     * Para que este possa ser utilizado o cod_classe não pode estar vazio
     * @return void
     */
    public function excluir() {
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('delete from classe where cod_classe = ?');
        $result = $link->execute($stmt, array($this->cod_classe));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    /**
     * @method Classe consultar($Cod_Classe) para consulta do recurso
     * @static
     * @param integer $cod_classe chave primária para consulta
     * @return Classe retorna o recurso de acordo com a chave primária passada
     */
    public static function consultar(&$cod_classe) {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select * from classe where cod_classe = ?', array($cod_classe));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        if ($result->numRows() == 0) {
            throw new Exception("Classe inexistente");
        } elseif ($result->numRows() > 1) {
            throw new Exception("Mais de um Classe com o mesmo identificador, informe ao administrador");
        }
        $result->fetchInto($row);
        $classe = new Classe();
        $classe->setCod_classe($row['cod_classe']);
        $classe->setDescricao($row['descricao']);
        $classe->setCodigo($row['codigo']);
        $classe->setNome($row['nome']);
        return $classe;
    }

    /**
     * @method integer validar() para validação de unicidade do recurso
     * @access private
     * @return integer retorna 1 para garantir a unicidade, 0 para o oposto
     */
    private function validar() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select cod_classe from classe where descricao = ? and nome = ?', array($this->descricao, $this->nome));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        if ($result->numRows() > 0) {
            return 0;
        }
        return 1;
    }

    private function verificarVinculacao() {
        /*$banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('SELECT classe.cod_classe FROM classe, classe_usuario, detalhe_classe WHERE classe.cod_classe = ? AND (classe.cod_classe = classe_usuario.cod_classe OR  detalhe_classe.cod_classe = classe.cod_classe)', array($this->cod_classe));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }

        if ($result->numRows() > 0) {
            return 1;
        }*/
        return 0;
    }

    /**
     * @method array listar() para gerar listagem do recurso
     * @static
     * @return array retorna array com a listagem dos recursos de acordo com a chave primária passada para consulta, este listar gera uma lista das classes filhas
     */
    public function listar() {
        $banco = BancoDeDados::getInstance();
        $resultFilhos = $banco->getLink()->query('select * from classe classe_pai = ?', $this->cod_classe);
        if (DB::isError($resultFilhos)) {
            return $resultFilhos->getMessage();
        }
        $resultado = array();
        while ($resultFilhos->fetchInto($row)) {
            $classe = new Classe();
            $classe->setCod_classe($row['cod_classe']);
            $classe->setDescricao($row['descricao']);
            $classe->setCodigo($row['codigo']);
            $classe->setNome($row['nome']);
            $resultado[] = &$classe;
            unset($classe);
        }
        return $resultado;
    }

    /**
     * @method array listar() para gerar listagem do recurso
     * @static
     * @return array retorna array com a listagem dos recursos de acordo com a chave primária passada para consulta, este listar gera uma lista das classes filhas
     */
    public static function gerarArvore(&$cod_classe = null) {
        $banco = BancoDeDados::getInstance();
        if (is_null($cod_classe)) {
            $result = $banco->getLink()->query('select * from classe where classe_pai is null');
        } else {
            $result = $banco->getLink()->query('select * from classe where classe_pai = ?', $cod_classe);
        }
        if (DB::isError($result)) {
            return $result->getMessage();
        }
        $resultado = array();
        while ($result->fetchInto($row)) {
            $classe = new Classe();
            $classe->setCod_classe($row['cod_classe']);
            $classe->setDescricao($row['descricao']);
            $classe->setNome($row['nome']);
            $classe->setCodigo($row['codigo']);
            $classe->setClassesFilhas(Classe::gerarArvore($row['cod_classe']));
            $classe->setVinculado($classe->verificarVinculacao());
            $resultado[] = &$classe;
            unset($classe);
        }
        return $resultado;
    }

}
?>